package com.jblv.frame.common.fastdfs.fdfs;

import com.jblv.frame.common.fastdfs.FastDfsUtils;
import com.jblv.frame.common.utils.ProjectPathUtils;
import com.jblv.frame.common.utils.PropertiesUtils;
import org.apache.commons.lang3.StringUtils;
import org.csource.common.MyException;
import org.csource.fastdfs.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;

/**
 * @author happyonion.yangtao
 * @version 1.0
 * @title ConnectionPool
 * @projectName jblv-frame
 * @packageName com.jblv.common.fastdfs.fdfs
 * @description ConnectionPool
 * @date Create at 2020/5/7 10:46
 * @since jdk1.8
 */


public class ConnectionPool {
    private static Logger logger = LoggerFactory.getLogger(ConnectionPool.class);
    private StorageServer storageServer = null;
    private static final String CONFIG_FILE_PATH = ProjectPathUtils.getPath("config/filesystem/fdfs_client.conf");
    private static int size = 10;
    private ConcurrentHashMap<StorageClient1, Object> busyConnectionPool = null;
    private ArrayBlockingQueue<StorageClient1> idleConnectionPool = null;
    private Object obj = new Object();
    private boolean doingInit = false;
    private static ConnectionPool instance = new ConnectionPool();

    public void close() {
        if (this.storageServer != null) {
            try {
                this.storageServer.close();
            } catch (IOException var2) {
                var2.printStackTrace();
            }
        }

    }

    public static ConnectionPool getConnectionPool() {
        return instance;
    }

    public StorageClient1 checkout(int waitTime) {
        StorageClient1 storageClient1 = null;

        try {
            if (this.isDoingInit() || this.idleConnectionPool.size() == 0 && this.busyConnectionPool.size() == 0) {
                return null;
            }

            storageClient1 = (StorageClient1)this.idleConnectionPool.poll((long)waitTime, TimeUnit.SECONDS);
            if (storageClient1 != null) {
                this.busyConnectionPool.put(storageClient1, this.obj);
            }
        } catch (InterruptedException var4) {
            storageClient1 = null;
            var4.printStackTrace();
        }

        return storageClient1;
    }

    public void checkin(StorageClient1 storageClient1) {
        if (this.busyConnectionPool.remove(storageClient1) != null) {
            this.idleConnectionPool.add(storageClient1);
        }

    }

    public void drop(StorageClient1 storageClient1) {
        if (!this.isDoingInit()) {
            synchronized(this) {
                if (!this.isDoingInit()) {
                    this.setDoingInit(true);
                    this.init(size);
                }

            }
        }
    }

    private ConnectionPool() {
        this.init(size);
    }

    private void init(int size) {
        this.busyConnectionPool = new ConcurrentHashMap();
        this.idleConnectionPool = new ArrayBlockingQueue(size);
        this.initClientGlobal();
        TrackerServer trackerServer = null;

        try {
            StorageClient1 storageClient1 = null;

            for(int i = 0; i < size; ++i) {
                TrackerClient trackerClient = new TrackerClient();
                trackerServer = trackerClient.getConnection();
                ProtoCommon.activeTest(trackerServer.getSocket());
                storageClient1 = new StorageClient1(trackerServer, this.storageServer);
                this.idleConnectionPool.add(storageClient1);
                if (trackerServer != null) {
                    try {
                        trackerServer.close();
                    } catch (IOException var16) {
                        var16.printStackTrace();
                    }
                }
            }
        } catch (IOException var17) {
            var17.printStackTrace();
        } finally {
            if (trackerServer != null) {
                try {
                    trackerServer.close();
                } catch (IOException var15) {
                    var15.printStackTrace();
                }
            }

            this.setDoingInit(false);
        }

    }

    private void initClientGlobal() {
        File file = new File(CONFIG_FILE_PATH);
        if (file.exists()) {
            try {
                Map<String, String> properties = PropertiesUtils.getProperties(CONFIG_FILE_PATH);
                FastDfsUtils.HTTP_FAST_SERVER = (String)properties.get("ftpserver");
                if (StringUtils.isNotEmpty((CharSequence)properties.get("poolsize"))) {
                    size = Integer.valueOf((String)properties.get("poolsize"));
                }

                ClientGlobal.init(CONFIG_FILE_PATH);
            } catch (MyException var3) {
                var3.printStackTrace();
                logger.error("MyException file" + CONFIG_FILE_PATH);
            } catch (IOException var4) {
                var4.printStackTrace();
                logger.error("IOException file" + CONFIG_FILE_PATH);
            }
        }

    }

    public boolean isDoingInit() {
        return this.doingInit;
    }

    public void setDoingInit(boolean doingInit) {
        this.doingInit = doingInit;
    }
}

